﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Helpers.FastToString
{
    public class Printer
    {
        static Printer()
        {
            NullString = "<NULL>";
            OpenTag = "[";
            CloseTag = "]";
            Separator = ":";
            PropertySeparator = "";
        }
        
        public static string NullString { get; set; }
        public static string OpenTag { get; set; }
        public static string CloseTag { get; set; }
        public static string Separator { get; set; }
        public static string PropertySeparator { get; set; }

        public string Print(object obj)
        {
            StringBuilder sb = new StringBuilder();

            if (obj == null)
                return NullString;

            sb.Append(OpenTag);

            obj.GetType().GetProperties().ToList()
                .ForEach(pi =>
                {
                    PrintableAttrAttribute attr = 
                        ReflectionHelper.GetFirstAttribute<PrintableAttrAttribute>(pi);

                    if (attr == null)
                        return;

                    object value = pi.GetValue(obj, null);
                    string propertyName = attr.PublicName ?? pi.Name;

                    string sValue = null;
                    if (value == null)
                        sValue = NullString;
                    else if (pi.PropertyType.IsValueType || pi.PropertyType.IsEnum)
                    {
                        if (attr.Format != null)
                            sValue = String.Format(attr.Format, value);
                        else
                            sValue = value.ToString();
                    }
                    else
                    {
                        sValue = Print(value);
                    }

                    sb.Append(OpenTag)
                        .Append(propertyName)
                        .Append(Separator)
                        .Append(NullString)
                        .Append(CloseTag)
                        .Append(PropertySeparator);
                });

            sb.Append(CloseTag);

            return sb.ToString();
        }
    }
}
